import java.util.BitSet;




/**
 * This class contains methods to check errors because of bitwidth scaling
 * If result rounding is enable then it rounds result according to the bitwidth
 * entered by user. 
 * 
 * @author kspatel
 *
 */

 public class Bitwidth_Manipulation
{
	 public static boolean final_result=false;

	public static boolean Overflow_Error_Check(long input_data_to_check)
	{
		// Flag to indicate rounding error 
		
		boolean overflow_error = false;
		
		/*
		 * If input data is negative then we will check weather the absolute value of
		 * the input data for 2^bitwidth -1 and hence >= is used. 
		 */
		//System.out.println(ISS_SIMD_Advance_Settings.user_entered_bitwidth);

		if (input_data_to_check < 0)
		{
			if (((Math.pow(2, (ISS_SIMD_Advance_Settings.user_entered_bitwidth)*2))/2) <= Math.abs(input_data_to_check))
				overflow_error = true;
		}
		
		/*
		 * If input data is positive then we will check weather the absolute value of
		 * the input data for 2^bitwidth and hence > is used. 
		 */

		if (input_data_to_check>=0)
		{
			if (((Math.pow(2, (ISS_SIMD_Advance_Settings.user_entered_bitwidth)*2))/2) < Math.abs(input_data_to_check))
				overflow_error = true;
		}

		return overflow_error; 
	}
	
	public static long Round_Result(long input_data)
	{
		
		boolean error=false;
		long rounded_data = input_data;
		error = Overflow_Error_Check(input_data);
		
		/*
		 * This is simple rounding scheme.
		 * 1) First it checks whether there is rounding error or not.
		 * 2) If there is rounding error then it rounds the data to the maximum 
		 * 	  positive or maximum negative depending on the sign of the data. 
		 */
		
		if(error)
		{
		//System.out.println(input_data);

		/*
		 * As for bitwidth on N the maximum positive can be (2^N)-1, we will
		 * round the data for the same value.
		 */
		
		if (input_data<0)
		rounded_data =  (long) (((Math.pow(2, (ISS_SIMD_Advance_Settings.user_entered_bitwidth)*2))/2)*(-1));
		
		/*
		 * As for bitwidth on N the maximum positive can be -(2^N), we will
		 * round the data for the same value.
		 */
		
		if (input_data>0)
			rounded_data= (long) (((Math.pow(2, (ISS_SIMD_Advance_Settings.user_entered_bitwidth)*2))/2)-1);
		
		
		//System.out.println("after  rounding " + rounded_data);
		
		}
		
		/*
		boolean error=false;
		error = Overflow_Error_Check(input_data);
		int rounded_data = input_data;
		if(error)
		{
			int difference;
		int rounding_index;
		String input_data_binary;
		System.out.println(input_data);
//		difference = ((2^ISS_SIMD_Advance_Settings.user_entered_bitwidth)/2) - input_data;
		difference =  Math.abs(input_data)-((int)Math.pow(2, ISS_SIMD_Advance_Settings.user_entered_bitwidth)/2) ;
		System.out.println("difference " + difference);
		
		rounding_index = (int)Math.ceil(Math.log10(Math.abs(difference))/Math.log10(2));
		//rounding_index = 5;
		System.out.println("rounding_index " + rounding_index);
		
		input_data_binary = Integer.toBinaryString(Math.abs(input_data));
		
		//rounded_data = input_data - ((int)Math.pow(2,rounding_index));
		
		//Taking the lower rounding_index bits.
		
//		input_data_binary = Integer.toBinaryString(input_data);
		System.out.println("Input in binary  " + input_data_binary);
		//temp = (BitSet)input_data;
		
		int b=0;
		String s;
		
		
		s = input_data_binary.substring(input_data_binary.length()-rounding_index);
		System.out.println("length " + input_data_binary.length());
		
		System.out.println("s=" + s);
//		for(int i=0;i<rounding_index;i++)
//			
//		{
//		//	if ((input_data && (Math.pow(2, i)))==1)
//			b = input_data_binary.codePointAt(i);		
//			System.out.println("b=" + b);
//			
//			//	rounded_data = input_data - (int)Math.pow(2,i);
//				
//		
//		}
		//b = Integer.parseInt(s);
		b= Integer.parseInt(s, 2);
		
		System.out.println("b= "+b);
		
//		b= b*(-1);
//		
//		System.out.println("b= "+b);
		
		
//		if (input_data>0)
//		rounded_data = input_data - b-1;
			rounded_data = Math.abs(input_data) - b -1;
		
		if (input_data<0)
//			rounded_data = input_data + b;
//		rounded_data =  Math.abs(input_data) - b;
		rounded_data = (rounded_data+1) * (-1);
		if (input_data==0)
			rounded_data=input_data;
		
		//rounded_data = input_data &  (int)(Math.pow(2,rounding_index));
		
		System.out.println("after  rounding " + rounded_data);
		rounded_data =  input_data >>rounding_index;
			System.out.println("after  rounding " + rounded_data);
			rounded_data = input_data <<rounding_index;
			System.out.println("after  rounding " + rounded_data);
		}
		*/
		return rounded_data;
	}
	
	
	public static void main(String args[])
	
	{
	
		int a = -120;
		Round_Result(a);
	}


}